<!DOCTYPE html>


<html theme="dark" showBanner="true" hasBanner="false" > 
<link href="https://cdn.staticfile.org/font-awesome/6.4.2/css/fontawesome.min.css" rel="stylesheet">
<link href="https://cdn.staticfile.org/font-awesome/6.4.2/css/brands.min.css" rel="stylesheet">
<link href="https://cdn.staticfile.org/font-awesome/6.4.2/css/solid.min.css" rel="stylesheet">
<script src="/hexo-blog/js/color.global.min.js" ></script>
<script src="/hexo-blog/js/load-settings.js" ></script>
<head>
  <meta charset="utf-8">
  
  
  

  
  <title>前端脚手架：从入门到进阶——CLI常用的npm包(二) | bressanone</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <link rel="preload" href="/hexo-blog/css/fonts/Roboto-Regular.ttf" as="font" type="font/ttf" crossorigin="anonymous">
  <link rel="preload" href="/hexo-blog/css/fonts/Roboto-Bold.ttf" as="font" type="font/ttf" crossorigin="anonymous">

  <meta name="description" content="这是我参与11月更文挑战的第11天，活动详情查看：2021最后一次更文挑战 上一节介绍了两个交互的库，这一节再介绍文件与模板操作的几个库 文件操作脚手架运行过程中的文件操作可能会比较繁杂，而node原生的fs api并不友好，借助优秀的文件操作库能帮助我们事半功倍。 fs-extrafs-extra对原生的fs对象进行了扩展，增加了一些方便的api，比如创建多个目录，复制，移动、读写json等，a">
<meta property="og:type" content="article">
<meta property="og:title" content="前端脚手架：从入门到进阶——CLI常用的npm包(二)">
<meta property="og:url" content="http://example.com/2021/11/11/%E5%89%8D%E7%AB%AF%E8%84%9A%E6%89%8B%E6%9E%B6%EF%BC%9A%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E2%80%94%E2%80%94CLI%E5%B8%B8%E7%94%A8%E7%9A%84npm%E5%8C%85(%E4%BA%8C)/index.html">
<meta property="og:site_name" content="bressanone">
<meta property="og:description" content="这是我参与11月更文挑战的第11天，活动详情查看：2021最后一次更文挑战 上一节介绍了两个交互的库，这一节再介绍文件与模板操作的几个库 文件操作脚手架运行过程中的文件操作可能会比较繁杂，而node原生的fs api并不友好，借助优秀的文件操作库能帮助我们事半功倍。 fs-extrafs-extra对原生的fs对象进行了扩展，增加了一些方便的api，比如创建多个目录，复制，移动、读写json等，a">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://example.com/2021/11/11/imgs/744095f84fc54d0faa6a002ecd90045f.png">
<meta property="og:image" content="http://example.com/2021/11/11/imgs/f904fc883f7942fd809e7e09c84ac5ef.png">
<meta property="article:published_time" content="2021-11-10T16:00:00.000Z">
<meta property="article:modified_time" content="2024-04-04T15:27:03.276Z">
<meta property="article:author" content="Zachary">
<meta property="article:tag" content="前端">
<meta property="article:tag" content="JavaScript">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://example.com/2021/11/11/imgs/744095f84fc54d0faa6a002ecd90045f.png">
  
  
    <link rel="icon" media="(prefers-color-scheme: light)" href="/hexo-blog/images/favicon-light-32.png" sizes="32x32">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/hexo-blog/images/favicon-light-128.png" sizes="128x128">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/hexo-blog/images/favicon-light-180.png" sizes="180x180">
    <link rel="icon" media="(prefers-color-scheme: light)" href="/hexo-blog/images/favicon-light-192.png" sizes="192x192">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/hexo-blog/images/favicon-dark-32.png" sizes="32x32">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/hexo-blog/images/favicon-dark-128.png" sizes="128x128">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/hexo-blog/images/favicon-dark-180.png" sizes="180x180">
    <link rel="icon" media="(prefers-color-scheme: dark)" href="/hexo-blog/images/favicon-dark-192.png" sizes="192x192">
  
  
<link rel="stylesheet" href="/hexo-blog/css/style.css">

<meta name="generator" content="Hexo 7.1.1"></head>

<body>
  
   
  <div id="main-grid" class="  ">
    <div id="nav" class=""  >
      <navbar id="navbar">
  <nav id="title-nav">
    <a href="/hexo-blog/">
      <div id="vivia-logo">
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
      </div>
      <div>bressanone </div>
    </a>
  </nav>
  <nav id="main-nav">
    
      <a class="main-nav-link" href="/hexo-blog/">主页</a>
    
      <a class="main-nav-link" href="/hexo-blog/archives">归档</a>
    
      <a class="main-nav-link" href="/hexo-blog/about">关于</a>
    
  </nav>
  <nav id="sub-nav">
    <a id="theme-btn" class="nav-icon">
      <span class="light-mode-icon"><svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M438.5-829.913v-48q0-17.452 11.963-29.476 11.964-12.024 29.326-12.024 17.363 0 29.537 12.024t12.174 29.476v48q0 17.452-11.963 29.476-11.964 12.024-29.326 12.024-17.363 0-29.537-12.024T438.5-829.913Zm0 747.826v-48q0-17.452 11.963-29.476 11.964-12.024 29.326-12.024 17.363 0 29.537 12.024t12.174 29.476v48q0 17.452-11.963 29.476-11.964 12.024-29.326 12.024-17.363 0-29.537-12.024T438.5-82.087ZM877.913-438.5h-48q-17.452 0-29.476-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537t29.476-12.174h48q17.452 0 29.476 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T877.913-438.5Zm-747.826 0h-48q-17.452 0-29.476-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537T82.087-521.5h48q17.452 0 29.476 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T130.087-438.5Zm660.174-290.87-34.239 32q-12.913 12.674-29.565 12.174-16.653-.5-29.327-13.174-12.674-12.673-12.554-28.826.12-16.152 12.794-28.826l33-35q12.913-12.674 30.454-12.674t30.163 12.847q12.709 12.846 12.328 30.826-.38 17.98-13.054 30.653ZM262.63-203.978l-32 34q-12.913 12.674-30.454 12.674t-30.163-12.847q-12.709-12.846-12.328-30.826.38-17.98 13.054-30.653l33.239-31q12.913-12.674 29.565-12.174 16.653.5 29.327 13.174 12.674 12.673 12.554 28.826-.12 16.152-12.794 28.826Zm466.74 33.239-32-33.239q-12.674-12.913-12.174-29.565.5-16.653 13.174-29.327 12.673-12.674 28.826-13.054 16.152-.38 28.826 12.294l35 33q12.674 12.913 12.674 30.454t-12.847 30.163q-12.846 12.709-30.826 12.328-17.98-.38-30.653-13.054ZM203.978-697.37l-34-33q-12.674-12.913-13.174-29.945-.5-17.033 12.174-29.707t31.326-13.293q18.653-.62 31.326 13.054l32 34.239q11.674 12.913 11.174 29.565-.5 16.653-13.174 29.327-12.673 12.674-28.826 12.554-16.152-.12-28.826-12.794ZM480-240q-100 0-170-70t-70-170q0-100 70-170t170-70q100 0 170 70t70 170q0 100-70 170t-170 70Zm-.247-82q65.703 0 111.475-46.272Q637-414.544 637-480.247t-45.525-111.228Q545.95-637 480.247-637t-111.475 45.525Q323-545.95 323-480.247t45.525 111.975Q414.05-322 479.753-322ZM481-481Z"/></svg></span>
      <span class="dark-mode-icon"><svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M480.239-116.413q-152.63 0-258.228-105.478Q116.413-327.37 116.413-480q0-130.935 77.739-227.435t206.304-125.043q43.022-9.631 63.87 10.869t3.478 62.805q-8.891 22.043-14.315 44.463-5.424 22.42-5.424 46.689 0 91.694 64.326 155.879 64.325 64.186 156.218 64.186 24.369 0 46.978-4.946 22.609-4.945 44.413-14.076 42.826-17.369 62.967 1.142 20.142 18.511 10.511 61.054Q807.174-280 712.63-198.206q-94.543 81.793-232.391 81.793Zm0-95q79.783 0 143.337-40.217 63.554-40.218 95.793-108.283-15.608 4.044-31.097 5.326-15.49 1.283-31.859.805-123.706-4.066-210.777-90.539-87.071-86.473-91.614-212.092-.24-16.369.923-31.978 1.164-15.609 5.446-30.978-67.826 32.478-108.282 96.152Q211.652-559.543 211.652-480q0 111.929 78.329 190.258 78.329 78.329 190.258 78.329ZM466.13-465.891Z"/></svg></span>
    </a>
    
    <div id="nav-menu-btn" class="nav-icon">
      <svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M177.37-252.282q-17.453 0-29.477-11.964-12.024-11.963-12.024-29.326t12.024-29.537q12.024-12.174 29.477-12.174h605.26q17.453 0 29.477 11.964 12.024 11.963 12.024 29.326t-12.024 29.537q-12.024 12.174-29.477 12.174H177.37Zm0-186.218q-17.453 0-29.477-11.963-12.024-11.964-12.024-29.326 0-17.363 12.024-29.537T177.37-521.5h605.26q17.453 0 29.477 11.963 12.024 11.964 12.024 29.326 0 17.363-12.024 29.537T782.63-438.5H177.37Zm0-186.217q-17.453 0-29.477-11.964-12.024-11.963-12.024-29.326t12.024-29.537q12.024-12.174 29.477-12.174h605.26q17.453 0 29.477 11.964 12.024 11.963 12.024 29.326t-12.024 29.537q-12.024 12.174-29.477 12.174H177.37Z"/></svg>
    </div>
  </nav>
</navbar>
<div id="nav-dropdown" class="hidden">
  <div id="dropdown-link-list">
    
      <a class="nav-dropdown-link" href="/hexo-blog/">主页</a>
    
      <a class="nav-dropdown-link" href="/hexo-blog/archives">归档</a>
    
      <a class="nav-dropdown-link" href="/hexo-blog/about">关于</a>
    
     
    </div>
</div>
<script>
  let dropdownBtn = document.getElementById("nav-menu-btn");
  let dropdownEle = document.getElementById("nav-dropdown");
  dropdownBtn.onclick = function() {
    dropdownEle.classList.toggle("hidden");
  }
</script>
    </div>
    <div id="sidebar-wrapper">
      <sidebar id="sidebar">
  
    <div class="widget-wrap">
  <div class="info-card">
    <div class="avatar">
      
      <div class="img-dim"></div>
    </div>
    <div class="info">
      <div class="username">Zachary </div>
      <div class="dot"></div>
      <div class="subtitle"> </div>
      <div class="link-list">
        
          <a class="link-btn" target="_blank" rel="noopener" href="https://github.com/zzy1661" title="GitHub"><i class="fa-brands fa-github"></i></a>
         
      </div>  
    </div>
  </div>
</div>

  
  <div class="sticky">
    
      


  <div class="widget-wrap">
    <div class="widget">
      <h3 class="widget-title">分类</h3>
      <div class="category-box">
            <a class="category-link" href="/hexo-blog/categories/%E5%89%8D%E7%AB%AF%E7%AC%94%E8%AE%B0/">
                前端笔记
                <div class="category-count">78</div>
            </a>
        
            <a class="category-link" href="/hexo-blog/categories/%E7%AE%97%E6%B3%95%E6%89%8B%E5%86%8C/">
                算法手册
                <div class="category-count">7</div>
            </a>
        </div>
    </div>
  </div>


    
      
  <div class="widget-wrap">
    <div class="widget">
      <h3 class="widget-title">标签</h3>
      <ul class="widget-tag-list" itemprop="keywords"><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Ant-Design/" rel="tag">Ant Design</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/CSS/" rel="tag">CSS</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Canvas/" rel="tag">Canvas</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Docker/" rel="tag">Docker</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/ECMAScript-6/" rel="tag">ECMAScript 6</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/JavaScript/" rel="tag">JavaScript</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Less/" rel="tag">Less</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/MobX/" rel="tag">MobX</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/MongoDB/" rel="tag">MongoDB</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/NPM/" rel="tag">NPM</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/NestJS/" rel="tag">NestJS</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Node-js/" rel="tag">Node.js</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Postman/" rel="tag">Postman</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/React-js/" rel="tag">React.js</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Redux/" rel="tag">Redux</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/TypeScript/" rel="tag">TypeScript</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/UML/" rel="tag">UML</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Webpack/" rel="tag">Webpack</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/Yeoman/" rel="tag">Yeoman</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E5%89%8D%E7%AB%AF/" rel="tag">前端</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E6%9E%B6%E6%9E%84/" rel="tag">架构</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/" rel="tag">正则表达式</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E6%BA%90%E7%A0%81/" rel="tag">源码</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E7%88%AC%E8%99%AB/" rel="tag">爬虫</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E7%AE%97%E6%B3%95/" rel="tag">算法</a></li><li class="widget-tag-list-item"><a class="widget-tag-list-link" href="/hexo-blog/tags/%E9%9D%A2%E8%AF%95/" rel="tag">面试</a></li></ul>
    </div>
  </div>


    
  </div>
</sidebar>
    </div>
    <div id="content-body">
       


<article id="post-前端脚手架：从入门到进阶——CLI常用的npm包(二)" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  
    
   
  <div class="article-inner">
    <div class="article-main">
      <header class="article-header">
        
<div class="main-title-bar">
  <div class="main-title-dot"></div>
  
    
      <h1 class="p-name article-title" itemprop="headline name">
        前端脚手架：从入门到进阶——CLI常用的npm包(二)
      </h1>
    
  
</div>

        <div class='meta-info-bar'>
          <div class="meta-info">
  <time class="dt-published" datetime="2021-11-10T16:00:00.000Z" itemprop="datePublished">2021-11-11</time>
</div>
          <div class="need-seperator meta-info">
            <div class="meta-cate-flex">
  
  <a class="meta-cate-link" href="/hexo-blog/categories/%E5%89%8D%E7%AB%AF%E7%AC%94%E8%AE%B0/">前端笔记</a>
   
</div>
  
          </div>
          <div class="wordcount need-seperator meta-info">
            4.5k 词 
          </div>
        </div>
        
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/hexo-blog/tags/JavaScript/" rel="tag">JavaScript</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/hexo-blog/tags/%E5%89%8D%E7%AB%AF/" rel="tag">前端</a></li></ul>

      </header>
      <div class="e-content article-entry" itemprop="articleBody">
        
          <p>这是我参与11月更文挑战的第11天，活动详情查看：<a target="_blank" rel="noopener" href="https://juejin.cn/post/7023643374569816095/" title="https://juejin.cn/post/7023643374569816095/">2021最后一次更文挑战</a></p>
<p>上一节介绍了两个交互的库，这一节再介绍文件与模板操作的几个库</p>
<h2 id="文件操作"><a href="#文件操作" class="headerlink" title="文件操作"></a>文件操作</h2><p>脚手架运行过程中的文件操作可能会比较繁杂，而node原生的fs api并不友好，借助优秀的文件操作库能帮助我们事半功倍。</p>
<h3 id="fs-extra"><a href="#fs-extra" class="headerlink" title="fs-extra"></a><a href="https://github.com%2Fjprichardson%2Fnode-fs-extra" title="https://github.com/jprichardson/node-fs-extra">fs-extra</a></h3><p>fs-extra对原生的fs对象进行了扩展，增加了一些方便的api，比如创建多个目录，复制，移动、读写json等，api调用方式也很简单，支持同步和异步，并且增加了Promise支持：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&#x27;fs-extra&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> src = <span class="string">&#x27;/tmp/file.txt&#x27;</span></span><br><span class="line"><span class="keyword">const</span> dest = <span class="string">&#x27;/tmp/this/path/does/not/exist/file.txt&#x27;</span></span><br><span class="line"><span class="comment">// 移动</span></span><br><span class="line">fs.<span class="title function_">move</span>(src, dest)</span><br><span class="line">.<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;success!&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">catch</span>(<span class="function"><span class="params">err</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">error</span>(err)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">// 复制</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">example</span> () &#123;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> fs.<span class="title function_">copy</span>(<span class="string">&#x27;/tmp/myfile&#x27;</span>, <span class="string">&#x27;/tmp/mynewfile&#x27;</span>)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;success!&#x27;</span>)</span><br><span class="line">  &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">error</span>(err)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">example</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 同步删除</span></span><br><span class="line">fs.<span class="title function_">emptyDirSync</span>(<span class="string">&#x27;/tmp/some/dir&#x27;</span>)</span><br></pre></td></tr></table></figure>

<h3 id="mem-fs-editor"><a href="#mem-fs-editor" class="headerlink" title="mem-fs-editor"></a><a href="https://github.com%2Fsboudrias%2Fmem-fs-editor" title="https://github.com/sboudrias/mem-fs-editor">mem-fs-editor</a></h3><p>Yeoman内置的文件操作库就是men-fs-editor,不仅增加了一些友好的api，还能能方便我们对模板文件进行操作。</p>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">var <span class="attr">memFs</span> = require(<span class="string">&quot;mem-fs&quot;</span>)<span class="comment">;</span></span><br><span class="line">var <span class="attr">editor</span> = require(<span class="string">&quot;mem-fs-editor&quot;</span>)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">var <span class="attr">store</span> = memFs.create()<span class="comment">;</span></span><br><span class="line">var <span class="attr">fs</span> = editor.create(store)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">fs.write(&quot;somefile.js&quot;, &quot;var <span class="attr">a</span> = <span class="number">1</span><span class="comment">;&quot;);</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>它的模板语法为<a href="http://ejs.co%2F" title="http://ejs.co/">ejs</a></p>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const <span class="attr">filepath</span> = path.join(__dirname, <span class="string">&#x27;fixtures/file-tpl.txt&#x27;</span>)<span class="comment">; </span></span><br><span class="line">const <span class="attr">newPath</span> = <span class="string">&#x27;/new/path/file.txt&#x27;</span><span class="comment">;  </span></span><br><span class="line">fs.copyTpl(filepath, newPath, &#123;name: &#x27;new content&#x27;&#125;)<span class="comment">;</span></span><br></pre></td></tr></table></figure>

<p>另外它能对文件进行批操作全部完成后再一次性写入磁盘，能够避免过程中对文件的多次操作造成的意外冲突。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">const</span> filesystem = <span class="built_in">require</span>(<span class="string">&#x27;fs&#x27;</span>);</span><br><span class="line"></span><br><span class="line">fs.<span class="title function_">append</span>(<span class="string">&#x27;./append.txt&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, &#123;<span class="attr">create</span>: <span class="literal">true</span>&#125;);</span><br><span class="line">filesystem.<span class="title function_">stat</span>(<span class="string">&#x27;./append.txt&#x27;</span>,<span class="function">(<span class="params">err</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="keyword">if</span>(err) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;commit前：文件不存在&#x27;</span>);</span><br><span class="line">    fs.<span class="title function_">commit</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;commit后&#x27;</span>,filesystem.<span class="title function_">statSync</span>(<span class="string">&#x27;./append.txt&#x27;</span>))</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p><img src="./../imgs/744095f84fc54d0faa6a002ecd90045f.png" alt="image.png"></p>
<h2 id="模板操作"><a href="#模板操作" class="headerlink" title="模板操作"></a>模板操作</h2><h3 id="handlebars"><a href="#handlebars" class="headerlink" title="handlebars"></a><a href="https://github.com%2Fhandlebars-lang%2Fhandlebars.js" title="https://github.com/handlebars-lang/handlebars.js">handlebars</a></h3><p>handlebars也是一个常见的模板工具</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">var</span> Handlebars = require(&#x27;handlebars&#x27;);</span><br><span class="line"><span class="selector-tag">var</span> source = &quot;&lt;<span class="selector-tag">p</span>&gt;Hello, my name is &#123;&#123;name&#125;&#125;. <span class="selector-tag">I</span> am <span class="selector-tag">from</span> &#123;&#123;hometown&#125;&#125;. <span class="selector-tag">I</span> have &quot; +</span><br><span class="line">             &quot;&#123;&#123;kids<span class="selector-class">.length</span>&#125;&#125; kids:&lt;/p&gt;<span class="string">&quot; +</span></span><br><span class="line"><span class="string">             &quot;</span>&lt;ul&gt;&#123;&#123;<span class="selector-id">#kids</span>&#125;&#125;&lt;<span class="selector-tag">li</span>&gt;&#123;&#123;name&#125;&#125; is &#123;&#123;age&#125;&#125;&lt;/<span class="selector-tag">li</span>&gt;&#123;&#123;/kids&#125;&#125;&lt;/<span class="selector-tag">ul</span>&gt;&quot;;</span><br><span class="line"><span class="selector-tag">var</span> template = Handlebars<span class="selector-class">.compile</span>(source);</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">var</span> data = &#123; &quot;name&quot;: <span class="string">&quot;Alan&quot;</span>, <span class="string">&quot;hometown&quot;</span>: <span class="string">&quot;Somewhere, TX&quot;</span>,</span><br><span class="line">             <span class="string">&quot;kids&quot;</span>: [&#123;&quot;name&quot;: <span class="string">&quot;Jimmy&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="string">&quot;12&quot;</span>&#125;, &#123;&quot;name&quot;: <span class="string">&quot;Sally&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="string">&quot;4&quot;</span>&#125;]&#125;;</span><br><span class="line"><span class="selector-tag">var</span> result = template(data);</span><br></pre></td></tr></table></figure>

<p>条件判断：</p>
<p>postcss.config.js.hbs:</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">module.exports</span> <span class="string">=</span> &#123;</span><br><span class="line">	<span class="attr">plugins:</span> [</span><br><span class="line">		<span class="string">require(&#x27;autoprefixer&#x27;)()<span class="template-variable">&#123;&#123;#if h5&#125;&#125;</span></span>,</span><br><span class="line">		<span class="string">require(&#x27;postcss-px-to-viewport&#x27;)(</span>&#123;</span><br><span class="line">			<span class="attr">viewportWidth:</span> <span class="number">375</span>,</span><br><span class="line">			<span class="attr">viewportHeight:</span> <span class="number">667</span>,</span><br><span class="line">			<span class="attr">unitPrecision:</span> <span class="number">5</span>,</span><br><span class="line">			<span class="attr">viewportUnit:</span> <span class="string">&#x27;vw&#x27;</span>,</span><br><span class="line">			<span class="attr">selectorBlackList:</span> [<span class="string">&#x27;NoVw&#x27;</span>],</span><br><span class="line">			<span class="attr">minPixelValue:</span> <span class="number">1</span>,</span><br><span class="line">			<span class="attr">mediaQuery:</span> <span class="literal">false</span></span><br><span class="line">		&#125;<span class="string">)</span></span><br><span class="line">		&#123;&#123;<span class="string">/if</span>&#125;&#125;</span><br><span class="line">	]</span><br><span class="line">&#125;<span class="string">;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="download-git-repo"><a href="#download-git-repo" class="headerlink" title="download-git-repo"></a><a href="https://gitlab.com%2Fflippidippi%2Fdownload-git-repo%23readme" title="https://gitlab.com/flippidippi/download-git-repo#readme">download-git-repo</a></h3><p>用git仓库维护项目模板也是一个常见的做法，这个工具简化将一个git仓库下载到指定目录的过程。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">download</span>(</span><br><span class="line"><span class="string">&#x27;https://mygitlab.com:flippidippi/download-git-repo-fixture#my-branch&#x27;</span>, </span><br><span class="line"><span class="string">&#x27;test/tmp&#x27;</span>, &#123; <span class="attr">clone</span>: <span class="literal">true</span> &#125;, <span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(err ? <span class="string">&#x27;Error&#x27;</span> : <span class="string">&#x27;Success&#x27;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h3 id="plop"><a href="#plop" class="headerlink" title="plop"></a><a href="https://github.com%2Fplopjs%2Fplop" title="https://github.com/plopjs/plop">plop</a></h3><p>快速创建模板代码的工具，可以简单理解为<a href="https://github.com%2FSBoudrias%2FInquirer.js%2F" title="https://github.com/SBoudrias/Inquirer.js/">inquirer</a> + <a href="https://github.com%2Fwycats%2Fhandlebars.js%2F" title="https://github.com/wycats/handlebars.js/">handlebar</a>，当项目中有一些复杂且有标准的文件需要编写时，可以抽象这套标准通过template生成。</p>
<p>package.json</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">   <span class="attr">&quot;addComponent&quot;</span><span class="punctuation">:</span> <span class="string">&quot;plop --plopfile ./plopfile.js&quot;</span></span><br><span class="line"> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;devDependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">   <span class="attr">&quot;change-case&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^4.1.2&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;plop&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.7.6&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>plopfile.js</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; pascalCase &#125; = <span class="keyword">require</span>(<span class="string">&quot;change-case&quot;</span>);</span><br><span class="line"></span><br><span class="line">module.exports = <span class="function"><span class="keyword">function</span> (<span class="params">plop</span>) </span>&#123;</span><br><span class="line">	plop.<span class="title function_ invoke__">setHelper</span>(<span class="string">&#x27;pascalCase&#x27;</span>, function (text) &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="title function_ invoke__">pascalCase</span>(text);</span><br><span class="line">	&#125;);</span><br><span class="line">	plop.<span class="title function_ invoke__">setGenerator</span>(<span class="string">&#x27;component&#x27;</span>, &#123;</span><br><span class="line">		</span><br><span class="line">		<span class="attr">description</span>: <span class="string">&#x27;add a component&#x27;</span>,</span><br><span class="line">		<span class="attr">prompts</span>: [&#123;</span><br><span class="line">			<span class="attr">type</span>: <span class="string">&#x27;input&#x27;</span>,</span><br><span class="line">			<span class="attr">name</span>: <span class="string">&#x27;name&#x27;</span>,</span><br><span class="line">			<span class="attr">message</span>: <span class="string">&#x27;component name&#x27;</span></span><br><span class="line">		&#125;],</span><br><span class="line">		<span class="attr">actions</span>: [&#123;</span><br><span class="line">			<span class="attr">type</span>: <span class="string">&#x27;add&#x27;</span>,</span><br><span class="line">			<span class="attr">path</span>: <span class="string">&#x27;src/components/&#123;&#123;pascalCase name&#125;&#125;/index.tsx&#x27;</span>,</span><br><span class="line">			<span class="attr">templateFile</span>: <span class="string">&#x27;templates/component.tsx.hbs&#x27;</span></span><br><span class="line">		&#125;]</span><br><span class="line">	&#125;);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>templates&#x2F;component.tsx.hbs</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; <span class="variable constant_">FC</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> &#123;&#123;pascalCase name&#125;&#125;: <span class="variable constant_">FC</span> = <span class="keyword">function</span> (<span class="params">props</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span>Component<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;&#123;pascalCase name&#125;&#125;;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>运行命令</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">npm run addComponent</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">&gt; </span><span class="language-bash">plop-demo@0.1.0 addComponent D:\personal\plop-demo</span></span><br><span class="line"><span class="meta prompt_">&gt; </span><span class="language-bash">plop --plopfile ./plopfile.js</span></span><br><span class="line"></span><br><span class="line">? component name test</span><br><span class="line">✔  ++ \src\components\Test\index.tsx</span><br></pre></td></tr></table></figure>

<p>生成文件</p>
<p><img src="./../imgs/f904fc883f7942fd809e7e09c84ac5ef.png" alt="image.png"></p>
<h2 id="未完待续"><a href="#未完待续" class="headerlink" title="未完待续"></a>未完待续</h2><p>以上就是文件和模板操作相关的几个常用第三方库。</p>
<p>下一节介绍其他小工具。</p>

        
      </div>

         
    </div>
    
     
  </div>
  
    
<nav id="article-nav">
  <a class="article-nav-btn left "
    
      href="/hexo-blog/2021/11/12/%E5%89%8D%E7%AB%AF%E8%84%9A%E6%89%8B%E6%9E%B6%EF%BC%9A%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E2%80%94%E2%80%94CLI%E5%B8%B8%E7%94%A8%E7%9A%84npm%E5%8C%85(%E4%B8%89)/"
      title="前端脚手架：从入门到进阶——CLI常用的npm包(三)"
     >
    <i class="fa-solid fa-angle-left"></i>
    <p class="title-text">
      
        前端脚手架：从入门到进阶——CLI常用的npm包(三)
        
    </p>
  </a>
  <a class="article-nav-btn right "
    
      href="/hexo-blog/2021/11/09/%E5%A6%82%E4%BD%95%E4%BD%BFTypeScript%E6%A0%B9%E6%8D%AE%E5%87%BD%E6%95%B0%E7%9A%84%E5%AE%9E%E5%8F%82%E6%8E%A8%E5%AF%BC%E5%85%B6%E8%BF%94%E5%9B%9E%E5%80%BC%E7%B1%BB%E5%9E%8B/"
      title="如何使TypeScript根据函数的实参推导其返回值类型"
     >

    <p class="title-text">
      
        如何使TypeScript根据函数的实参推导其返回值类型
        
    </p>
    <i class="fa-solid fa-angle-right"></i>
  </a>
</nav>


  
</article>





    </div>
    <div id="footer-wrapper">
      <footer id="footer">
  
  <div id="footer-info" class="inner">
    
    &copy; 2024 Zachary<br>
    <!-- Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> & Theme <a target="_blank" rel="noopener" href="https://github.com/saicaca/hexo-theme-vivia">Vivia</a> -->
      <a target="_blank" rel="noopener" href="https://beian.miit.gov.cn">苏ICP备20030005号-2</a>
  </div>
</footer>

    </div>
    <div class="back-to-top-wrapper">
    <button id="back-to-top-btn" class="back-to-top-btn hide" onclick="topFunction()">
        <i class="fa-solid fa-angle-up"></i>
    </button>
</div>

<script>
    function topFunction() {
        window.scroll({ top: 0, behavior: 'smooth' });
    }
    let btn = document.getElementById('back-to-top-btn');
    function scrollFunction() {
        if (document.body.scrollTop > 600 || document.documentElement.scrollTop > 600) {
            btn.classList.remove('hide')
        } else {
            btn.classList.add('hide')
        }
    }
    window.onscroll = function() {
        scrollFunction();
    }
</script>

  </div>
  <script src="/hexo-blog/js/light-dark-switch.js"></script>
</body>
</html>
